<?php

namespace app\admin\controller;

use app\common\controller\Backend;
use think\Db;

/**
 * 申请提现
 *
 * @icon fa fa-circle-o
 */
class UserWithdrawalApply extends Backend
{

    /**
     * UserWithdrawalApply模型对象
     * @var \app\admin\model\UserWithdrawalApply
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\UserWithdrawalApply;

    }



    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */


    /**
     * 查看
     */
    public function index()
    {
        //当前是否为关联查询
        $this->relationSearch = true;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();

            $list = $this->model
                    ->with(['user','order'])
                    ->where($where)
                    ->order($sort, $order)
                    ->paginate($limit);

            foreach ($list as $row) {
                
                $row->getRelation('user')->visible(['nickname']);
                $row->getRelation('order')->visible(['order_no']);
            }

            $total = \app\admin\model\User::where(['group_id' => 2])->sum('accrue_money');
            $deposit = \app\admin\model\User::where(['group_id' => 2])->sum('deposit');
            $wait = $this->model->where(['status'=>0])->sum('money');
            $yes = $this->model->where(['status'=>1])->sum('money');
            $spare = $total - $yes;

            $result = array("total" => $list->total(), "rows" => $list->items(), "extend" => ['total' => $total, 'deposit' => $deposit, 'wait' => $wait, 'yes' => $yes, 'spare' => $spare]);

            return json($result);
        }
        return $this->view->fetch();
    }


    /**
     * 编辑
     *
     * @param $ids
     * @return string
     * @throws DbException
     * @throws \think\Exception
     */
    public function edit($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
            $this->error(__('You have no permission'));
        }
        if (false === $this->request->isPost()) {
            $this->view->assign('row', $row);
            return $this->view->fetch();
        }
        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $params = $this->preExcludeFields($params);
        $result = false;
        Db::startTrans();
        try {
            //是否采用模型验证
            if ($this->modelValidate) {
                $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                $row->validateFailException()->validate($validate);
            }
            if($params['status'] == 1){
                
                // return $filePath = '/addons/epay/certs/';
                
                // 直接转账到零钱
                $openid = \app\admin\model\User::where(['id' => $row['user_id']])->value('openid');
                if(!$openid) $this->error(__('用户未绑定微信，无法提现'));
                $realname = \app\admin\model\MasterRealname::where(['user_id'=>$row['user_id']])->value('realname');
                if(!$realname) $this->error(__('请先实名认真'));
                $res = $this->transfer('电工师傅', getNewOrderNo(16), $row['money'], $openid, $realname);
                
                // file_put_contents(public_path() . "/transferlog.txt",json_encode($res).PHP_EOL,FILE_APPEND);
                if(isset($res['state']) && $res['state'] == 'WAIT_USER_CONFIRM'){
                    // 保存信息
                    $params['package_info'] = $res['package_info'];
                    
                    
                   $is_withdraw = \app\common\model\MoneyLog:: where(['user_id' => $row['user_id'], 'order_id' => $row['order_id']])->value('is_withdraw');
                   if(!$is_withdraw){
                       // 减少用户余额
                    \app\common\model\User::money(0-$row['money'], $row['user_id'], '提现');
                    // 标记为已提现
                    \app\common\model\MoneyLog::where(['user_id' => $row['user_id'], 'order_id' => $row['order_id']])->update(['is_withdraw' => 1]);
                   }
                    
                }else{
                    $this->error(__($res['state']));
                }
            }

            $result = $row->allowField(true)->save($params);
            Db::commit();
        } catch (ValidateException|PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if (false === $result) {
            $this->error(__('No rows were updated'));
        }
        $this->success('成功，等待用户确认');
    }
    
    
    
    
    /**
     * 商家转账到零钱（公众号：程序员在囧途）
     * @param $batch_name
     * @param $out_trade_no
     * @param $money
     * @param $openid
     * @throws BaseException
     */
    function transfer($batch_name, $out_trade_no, $money, $openid, $username)
    {
        $url = 'https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills';
        $pars = [];
        $pars['appid'] = 'wxa8e0ec7b7f70bdc7';
        $pars['out_bill_no'] = $out_trade_no;
        $pars['transfer_scene_id'] = '1005';
        $pars['openid'] = $openid;
        if ($money>0.5) {
            $pars['user_name'] = $this->getEncrypt($username);
        }
        $pars['transfer_amount'] = intval($money * 100);
        $pars['transfer_remark'] = $batch_name;
        $pars['notify_url'] = "https://www.weixin.qq.com/wxpay/pay.php";
        $pars['transfer_scene_report_infos'] = [
            [
                'info_type' => '岗位类型',
                'info_content' => $batch_name
            ],
            [
                'info_type' => '报酬说明',
                'info_content' => '工作佣金提现'
            ]
        ];
        \think\Log::log(json_encode($pars, JSON_UNESCAPED_UNICODE));
        //转账明细列表
        $token = $this->getToken($pars);// 获取token
        
        // return $token;
        $res = $this->https_request($url, json_encode($pars), $token);//发送请求
        $data = json_decode($res, true);
        return $data;
        // if(isset($data['batch_id']) && $data['batch_id']){
        //     return $data;
        // }
        // return [];
    }
    
    function get_Certificates()
    {

        $platformCertificateFilePath = $this->getCertPem()['wechatpayPem'];

        if(empty($platformCertificateFilePath)){

            return '';
        }

        $a = openssl_x509_parse(file_get_contents($platformCertificateFilePath));

        return !empty($a['serialNumberHex'])?$a['serialNumberHex']:'';
    }

    function getEncrypt($str) {
        //$str是待加密字符串
        $public_key_path = $this->getCertPem()['wechatpayPem'];
        
        // return $public_key_path;

        if(empty($public_key_path)){

            return '';
        }

        $public_key = file_get_contents($public_key_path);

        $encrypted = '';

        if (openssl_public_encrypt($str, $encrypted, $public_key, OPENSSL_PKCS1_OAEP_PADDING)) {
            //base64编码
            $sign = base64_encode($encrypted);
        } else {
            throw new Exception('encrypt failed');
        }
        return $sign;
    }
    
    function https_request($url, $data = null, $token)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, (string)$url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        //添加请求头
        $headers = [
            'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $token,
            'Accept: application/json',
            'Wechatpay-Serial: PUB_KEY_ID_0117093161422025030600356700000512',
            'Content-Type: application/json; charset=utf-8',
            'User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
        ];
        if (!empty($headers)) {
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        }
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }
    
    function getToken($pars)
    {
        
        // $url = 'https://api.mch.weixin.qq.com/v3/certificates';
        $url = 'https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills';
        $http_method = 'POST';//请求方法（GET,POST,PUT）
        $timestamp = time();//请求时间戳
        $url_parts = parse_url($url);//获取请求的绝对URL
        $nonce = $timestamp . rand('10000', '99999');//请求随机串
        $body = json_encode((object)$pars);//请求报文主体
        $stream_opts = [
            "ssl" => [
                "verify_peer" => false,
                "verify_peer_name" => false,
            ]
        ];
        try {
            $certPem = $this->getCertPem();
            // return $certPem;
            
            $apiclient_cert_path = $certPem['certPem'];
            $apiclient_key_path = $certPem['keyPem'];
            $apiclient_cert_arr = openssl_x509_parse(file_get_contents($apiclient_cert_path, false, stream_context_create($stream_opts)));
            $serial_no = $apiclient_cert_arr['serialNumberHex'];//证书序列号
            // return $serial_no;
            $mch_private_key = file_get_contents($apiclient_key_path, false, stream_context_create($stream_opts));//密钥
            $merchant_id = '1709316142';
            $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
            $message = $http_method . "\n" .
                $canonical_url . "\n" .
                $timestamp . "\n" .
                $nonce . "\n" .
                $body . "\n";
            openssl_sign($message, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption');
            $sign = base64_encode($raw_sign);//签名
            $schema = 'WECHATPAY2-SHA256-RSA2048';
            $token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
                $merchant_id, $nonce, $timestamp, $serial_no, $sign);//微信返回token
        } catch (\Exception $e) {
            throw $e;
        }
        return $token;
    }
    
    /**
     * 获取cert证书文件
     * @return array
     * @throws BaseException
     */
    function getCertPem()
    {
        // cert目录
        $filePath = ROOT_PATH . '/public/cert/wechat/';
        // $filePath = ROOT_PATH . '/addons/epay/certs/';
        return [
            'certPem' => $filePath . 'apiclient_cert.pem',
            'keyPem' => $filePath . 'apiclient_key.pem',
            'wechatpayPem' => $filePath . 'pub_key.pem',
        ];
    }

}
